package com.vip.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import static java.util.Calendar.*;

/**
 * 时间工具
 *
 * @authorLEON
 */
public class TimeUtils {
    public static final Byte MONTH = 1;
    public static final Byte QUARTER = 2;
    public static final Byte YEAR = 3;

    /**
     * 日期转换为字符串
     *
     * @param date 要转换的时间
     * @param pattern 转换格式
     * @return
     */
    public static String dateToString(Date date, String pattern) {
        if (date != null && pattern != null) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
            return dateFormat.format(date);
        } else {
            return "";
        }
    }

    /**
     * 字符串转换为日期
     *
     * @param date 要转换的字符串
     * @param pattern 要转换的日期类型
     * @return
     */
    public static Date stringToDate(String date, String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        try {
            return df.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取指定日期所在月份的开始时间
     *
     * @param date 指定日期
     * @return
     */
    public static Date getStartTimeOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        if (date != null) {
            c.setTime(date);
        }
        c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, c.getActualMinimum(HOUR_OF_DAY));
        c.set(Calendar.MINUTE, c.getActualMinimum(MINUTE));
        c.set(Calendar.SECOND, c.getActualMinimum(SECOND));
        c.set(Calendar.MILLISECOND, c.getActualMinimum(MILLISECOND));
        return c.getTime();
    }

    /**
     * 获取指定日期所在月份的最后时刻
     *
     * @param date 指定日期
     * @return
     */
    public static Date getLastTimeOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        if (date != null) {
            c.setTime(date);
        }
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, c.getActualMaximum(HOUR_OF_DAY));
        c.set(Calendar.MINUTE, c.getActualMaximum(MINUTE));
        c.set(Calendar.SECOND, c.getActualMaximum(SECOND));
        c.set(Calendar.MILLISECOND, c.getActualMaximum(MILLISECOND));
        return c.getTime();
    }

    /**
     * 获取指定日期所在季度的开始时间
     *
     * @param date 指定日期
     * @return
     */
    public static Date getStartTimeOfQuarter(Date date) {
        Calendar c = Calendar.getInstance();
        if (date != null) {
            c.setTime(date);
        }
        c.set(Calendar.MONTH, getStartMonthOfQuarter(c));
        c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, c.getActualMinimum(HOUR_OF_DAY));
        c.set(Calendar.MINUTE, c.getActualMinimum(MINUTE));
        c.set(Calendar.SECOND, c.getActualMinimum(SECOND));
        c.set(Calendar.MILLISECOND, c.getActualMinimum(MILLISECOND));
        return c.getTime();
    }

    /**
     * 获取指定日期所在季度的最后时刻
     *
     * @param date 指定日期
     * @return
     */
    public static Date getLastTimeOfQuarter(Date date) {
        Calendar c = Calendar.getInstance();
        if (date != null) {
            c.setTime(date);
        }
        c.set(Calendar.MONTH, getLastMonthOfQuarter(c));
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, c.getActualMaximum(HOUR_OF_DAY));
        c.set(Calendar.MINUTE, c.getActualMaximum(MINUTE));
        c.set(Calendar.SECOND, c.getActualMaximum(SECOND));
        c.set(Calendar.MILLISECOND, c.getActualMaximum(MILLISECOND));
        return c.getTime();
    }

    /**
     * 获取指定时间所在季度的开始月份
     *
     * @param c
     * @return
     */
    public static int getStartMonthOfQuarter(Calendar c) {
        int month = c.get(Calendar.MONTH);
        // 0,1,2|3,4,5|6,7,8|9,10,11
        if (month <= 2) {
            return 0;
        } else if (month <= 5) {
            return 3;
        } else if (month <= 8) {
            return 6;
        } else {
            return 9;
        }
    }

    /**
     * 获取指定时间所在季度的最后月份
     *
     * @param c
     * @return
     */
    public static int getLastMonthOfQuarter(Calendar c) {
        int month = c.get(Calendar.MONTH);
        // 0,1,2|3,4,5|6,7,8|9,10,11
        if (month <= 2) {
            return 2;
        } else if (month <= 5) {
            return 5;
        } else if (month <= 8) {
            return 8;
        } else {
            return 11;
        }
    }

    /**
     * 获取指定日期所在年份的开始时间
     *
     * @param date 指定日期
     * @return
     */
    public static Date getStartTimeOfYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.MONTH, c.getActualMinimum(MONTH));
        c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, c.getActualMinimum(HOUR_OF_DAY));
        c.set(Calendar.MINUTE, c.getActualMinimum(MINUTE));
        c.set(Calendar.SECOND, c.getActualMinimum(SECOND));
        c.set(Calendar.MILLISECOND, c.getActualMinimum(MILLISECOND));
        return c.getTime();
    }

    /**
     * 获取指定日期所在年份的最后时刻
     *
     * @param date 指定日期
     * @return
     */
    public static Date getLastTimeOfYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.MONTH, c.getActualMaximum(MONTH));
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, c.getActualMaximum(HOUR_OF_DAY));
        c.set(Calendar.MINUTE, c.getActualMaximum(MINUTE));
        c.set(Calendar.SECOND, c.getActualMaximum(SECOND));
        c.set(Calendar.MILLISECOND, c.getActualMaximum(MILLISECOND));
        return c.getTime();
    }

    /**
     * 判断该日期是否是该月的最后一天
     *
     * @param date 需要判断的日期
     * @return
     */
    public static boolean isLastDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH) == calendar.getActualMaximum(DAY_OF_MONTH);
    }

    /**
     * 获取指定时间所在周的起始时间
     *
     * @param date
     * @return
     */
    public static Date getStartTimeOfWeekMonday(Date date) {
        Calendar c = Calendar.getInstance();
        if (date != null) {
            c.setTime(date);
        }
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == Calendar.SUNDAY) {
            dayOfWeek = 8;
        }
        c.add(Calendar.DAY_OF_WEEK, Calendar.MONDAY - dayOfWeek);
        return getStartTimeOfDay(c.getTime());
    }

    /**
     * 获取指定时间所在周的结束时间
     *
     * @param date
     * @return
     */
    public static Date getEndTimeOfWeekSunday(Date date) {
        Calendar c = Calendar.getInstance();
        if (date != null) {
            c.setTime(date);
        }
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == Calendar.SUNDAY) {
            dayOfWeek = 8;
        }
        c.add(Calendar.DAY_OF_WEEK, 8 - dayOfWeek);
        return getEndTimeOfDay(c.getTime());
    }

    /**
     * 根据时间配置获取当周的工作日,从周一开始
     *
     * @param s   配置："1000111"
     * @param date
     * @return
     */
    public static List<Date> getWorkDayOfWeek(String s, Date date) {
        List<Date> workDateList = new ArrayList<Date>();
        //获取本周周一日期
        Date startTime = TimeUtils.getStartTimeOfWeekMonday(date);
        Calendar c = Calendar.getInstance();
        c.setTime(startTime);
        for (int i = 0; i < 7; i++) {
            c.setTime(startTime);
            c.add(Calendar.DATE, i);
            if (s.charAt(i) == '1') {
                workDateList.add(c.getTime());
            }
        }
        return workDateList;
    }

    /**
     * 根据月时间配置获取当月的所有工作日
     *
     * @param s    配置："1000111"
     * @param date
     * @return
     */
    // TODO 待补充
    public static List<Date> getWorkDayOfMonth(String s, Date date) {
        List<Date> workDateList = new ArrayList<Date>();
        //获取本周周一日期
        Date startTime = TimeUtils.getStartTimeOfWeekMonday(date);
        Calendar c = Calendar.getInstance();
        c.setTime(startTime);
        for (int i = 0; i < 7; i++) {
            c.setTime(startTime);
            c.add(Calendar.DATE, i);
            int dayOfMonth = c.get(Calendar.DAY_OF_MONTH) - 1;
            if (s.charAt(dayOfMonth) == '1') {
                workDateList.add(c.getTime());
            }
        }
        return workDateList;
    }

    /**
     * 判断日期是否在指定日期之间
     *
     * @param target    目标时间
     * @param startDate 开始时间
     * @param endDate   截止时间
     * @return
     */
    public static boolean isBetween(Date target, Date startDate, Date endDate) {
        return (target.after(startDate) || target.equals(startDate)) && (target.before(endDate) || target.equals(endDate));
    }

    /**
     * 获取传入日期的当天起始时间
     *
     * @param date
     * @return
     */
    public static Date getStartTimeOfDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(HOUR_OF_DAY));
        cal.set(Calendar.MINUTE, cal.getActualMinimum(MINUTE));
        cal.set(Calendar.SECOND, cal.getActualMinimum(SECOND));
        cal.set(Calendar.MILLISECOND, cal.getActualMinimum(MILLISECOND));
        return cal.getTime();
    }

    /**
     * 获取传入日期的当天最终时间
     *
     * @param date
     * @return
     */
    public static Date getEndTimeOfDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, cal.getActualMaximum(HOUR_OF_DAY));
        cal.set(Calendar.MINUTE, cal.getActualMaximum(MINUTE));
        cal.set(Calendar.SECOND, cal.getActualMaximum(SECOND));
        cal.set(Calendar.MILLISECOND, cal.getActualMaximum(MILLISECOND));
        return cal.getTime();
    }

    /**
     * 传入时间获取当前时间点的时分数据
     *
     * @param date
     * @return
     */
    public static String getTimePoint(Date date) {
        String dateString = TimeUtils.dateToString(date, "yyyy-MM-dd HH:mm:ss");
        String timePoint = dateString.substring(11, 16);
        return timePoint;
    }

    /**
     * 时间加法
     *
     * @param startTime 起始时间
     * @param addNumber 添加的数值
     * @param timeType  添加单位：6（日）11（时），12（分），13（秒）
     * @return
     */
    public static Date timeToAdd(Date startTime,int addNumber, int timeType){
        Calendar newTime = Calendar.getInstance();
        newTime.setTime(startTime);
        newTime.add(timeType, addNumber);
        return newTime.getTime();
    }

    /**
     * date2比date1多的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        //同一年
        if (year1 != year2) {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                //闰年
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
                    timeDistance += 366;
                } else {
                    //不是闰年
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else    //不同年
        {
            System.out.println("判断day2 - day1 : " + (day2 - day1));
            return day2 - day1;
        }
    }

    /**
     * 将秒数转换为天时分秒
     *
     * @param allSeconds
     * @return
     */
    public static String secondToDhms(long allSeconds) {
        String DateTimes = null;

        long days = allSeconds / (60 * 60 * 24);
        long hours = (allSeconds % (60 * 60 * 24)) / (60 * 60);
        long minutes = (allSeconds % (60 * 60)) / 60;
        long seconds = allSeconds % 60;

        if (days > 0) {
            DateTimes = days + "天 " + hours + "时" + minutes + "分" + seconds + "秒";
        } else if (hours > 0) {
            DateTimes = hours + "时" + minutes + "分" + seconds + "秒";
        } else if (minutes > 0) {
            DateTimes = minutes + "分" + seconds + "秒";
        } else {
            DateTimes = seconds + "秒";
        }
        return DateTimes;
    }

    public static void main(String[] args) {
        System.out.println(secondToDhms(445290));
    }
}
